/**
 * @author raelzhu
 * @version $Revision: 1.9 $
 */
Opal.Validator.Group = function(o) {
	this.validators = [];
}
Opal.Validator.Group.prototype = {
	addValidator: function(o) {
		this.validators.push(new Opal.Validator.Rule(o));
	},
	push: function(o) {
		this.validators.push(new Opal.Validator.Rule(o));
	},
	unshift: function(o) {
		this.validators.unshift(new Opal.Validator.Rule(o));
	},
	validate: function() {
		var errorMessages = [];
		var validators = this.validators;
		function doValidate(o) {
			$A(o.validators).each(function(it) {
				try {
					it.validate();
				} catch (e) {
					if (typeof o.index != 'undefined') {
						e = '[' + (o.index + 1) + '] ' + e;
					}
					o.errorMessages.push(e);
				}
			});
		}
		
		if (typeof this.iteration != 'undefined') {
			var item = this.iteration.item;
			var items = this.iteration.items;
			eval('context.' + items).each(function(it, index) {
				eval('context.' + item + '= context.' + items + '[' + index + ']');
				doValidate({
					validators: validators,
					errorMessages: errorMessages,
					index: index
				});
			});
		} else {
			doValidate({
				validators: validators,
				errorMessages: errorMessages
			});
		}
		return errorMessages;
	}
}
Opal.Validator.Group.groupMap = {};
Opal.Validator.Group.registerGroup = function(o) {
	Opal.Validator.Group.groupMap[o.id] = new Opal.Validator.Group(o);
}
Opal.Validator.Group.getGroup = function(id) {
	return Opal.Validator.Group.groupMap[id] || new Opal.Validator.Group();
}

Opal.Validator.Rule = function(o) {
	Object.extend(this, o);
	this.caption = this.caption || this.label;
}
Opal.Validator.Rule.prototype = {
	validate: function() {
		var flag = true;
		if (typeof this.enableWhen == 'function') {
			flag = this.enableWhen.call(this);
		}
		if (flag == true) {
			var method = Opal.Validator.Rule[this.type] || function(){};
			method.call(this);
		}
	}
}
Opal.Validator.Rule.required = function() {
	var value;
	try {
		value = eval('context.' + this.value);
	} catch (e) {
	}
	if (typeof value == 'undefined')
		throw getErrorMessage('VALUE_NOT_NULL', this.caption);
	if (value == null)
		throw getErrorMessage('VALUE_NOT_NULL', this.caption);
	if (value.toString().replace(/^\s*/, '') == '')
		throw getErrorMessage('VALUE_NOT_NULL', this.caption);
}
Opal.Validator.Rule.integer = function() {
	var value;
	try {
		value = eval('context.' + this.value);
		Opal.Log.debug('Opal.Validator.Rule.integer', 'this.value: ' + this.value);
	} catch (e) {}
	if (typeof value == 'undefined') {
		Opal.Log.warn('Opal.Validator.Rule.integer', 'value:' + this.value + ' is undefined!');
		return;
	}
	if (value == null) {
		Opal.Log.warn('Opal.Validator.Rule.integer', 'value:' + this.value + ' is null!');
		return;
	}
	if (value.toString().replace(/^\s*/, '') == '') {
		Opal.Log.warn('Opal.Validator.Rule.integer', 'value:' + this.value + ' is whitespace sequence!');
		return;
	}
	if (value.toString().indexOf('.') > -1 || isNaN(parseInt(value))) {
		throw getErrorMessage('VALUE_MUST_BE_INT', this.caption);
	}
}
Opal.Validator.Rule.number = function() {
	var value;
	try {
		value = eval('context.' + this.value);
	} catch (e) {}
	if (typeof value == 'undefined') return;
	if (value == null) return;
	if (value.toString().replace(/^\s*/, '') == '') return;
	if (isNaN(Number(value))) {
		throw getErrorMessage('VALUE_MUST_BE_NUMBER', this.caption);
	}
}
